<?php

namespace app\index\service;

use app\common\model\Consulting;
use app\common\model\ConsultingMessage;
use app\common\model\ConsultingServer;
use app\common\model\Member;
use app\common\model\Trade;
use app\common\service\SubscriptionMessageService;
use app\index\dao\TradeDao;
use app\index\model\UM as UM;
use app\index\traits\TradeBroadcastTrait;
use app\index\traits\TradeShareEstimateTrait;
use ShidianUtil\Utils\CheckUtil;
use think\exception\ValidateException;
use think\facade\Config;

/**
 * Class TradeConsultingServerService
 * @package app\trade\service
 */
class TradeConsultingServerService implements TradableInterface
{
    use TradeShareEstimateTrait;
    use TradeBroadcastTrait;

    // dao
    private TradeDao $tradeDao;

    public function __construct(TradeDao $tradeDao)
    {
        $this->tradeDao = $tradeDao;
    }

    /**
     * 新增
     * @param UM $user
     * @param array $params
     * @return  \app\common\model\Trade
     */
    public function add(UM $user, array $params): Trade
    {
        // 补齐参数，创建Trade
        $tradeType = TRADE_CONSULTING_SERVER;
        $tradeConfig = Config::get("trade.trades.$tradeType", []);
        $tradeTypeClass = $tradeConfig['className'] ?? '';

        $serverId = $params['serverId'] ?? null;
        $consultingId = $params['consultingId'] ?? null;
        $phone = $params['phone'] ?? '';

        // 渠道链路
        ['pf' => $pf, 'chain' => $chain, 'promotionGroupId' => $promotionGroupId] = getChainParams();

        // 推广回传
        $promotionFeedback = $params['promotionFeedback'] ?? null;

        // 服务
        $server = ConsultingServer::where('id', $serverId)
                                  ->where('serverType', '<>', ConsultingServer::FREE)
                                  ->find();
        if (!$server) {
            throw new ValidateException('该服务不存在，或已被删除');
        }
        // 如果是需要提供手机号的
        if ($server->isShowCallTel == '1') {
            if (is_blank($phone) || !CheckUtil::isPhoneNumber($phone)) {
                throw new ValidateException('请输入正确的手机号码');
            }
        }


        // 咨询
        $consulting = Consulting::where('id', $consultingId)
                                ->find();
        if (!$consulting) {
            throw new ValidateException('该咨询不存在，或已被删除');
        }
        if ($consulting->memberId != $user->id) {
            throw new ValidateException('您不能为他人购买服务');
        }
        if ($consulting->isEnd == 1) {
            throw new ValidateException('该咨询已完成，如需服务请重新发起');
        }

        $describe = $tradeConfig['name'] . '-' . $server->name;

        // 暂时没说优惠卷
        $showMoney = $server->showPrice;
        $totalMoney = $server->price;
        $payMoney = $totalMoney;
        $settleStatus = Trade::UNSETTLED;

        $phones = array_merge(Config::get('member.developerAccount', []), Config::get('member.testAccount', []));
        if (in_array($user->phone, $phones)) {
            $payMoney = '0.01';
            $settleStatus = Trade::NOTSETTLE;
        }

        if ($payMoney < 0.01) {
            throw new ValidateException('订单价格应该大于0');
        }

        $tradeParams = [
            'memberId' => $user->id,
            'orderNoPre' => 'SR',
            'describe' => $describe,
            'tradeType' => $tradeType,
            'tradeTypeClass' => $tradeTypeClass,
            'consultingId' => $consultingId,
            'serverId' => $server->id,
            'showMoney' => $showMoney,
            'totalMoney' => $totalMoney,
            'payMoney' => $payMoney,
            'payStatus' => Trade::UNPAID,
            'payExpTime' => time() + 3600,
            'settleStatus' => $settleStatus,
            'pf' => $pf,
            'chain' => $chain,
            'promotionGroupId' => $promotionGroupId,
            'attach' => [
                'attach' => '',
                'memberPhone' => $phone,
                'promotionFeedback' => $promotionFeedback,
            ],
        ];

        $record = $this->tradeDao->insertTrade($tradeParams);

        // 触发订单创建时间
        event('TradeCreated', $record);

        return $record;
    }

    // 完成订单
    public function completionTrade(Trade $trade)
    {
        // 购买服务成功

        // 咨询
        $consulting = Consulting::where('id', $trade->consultingId)->find();

        // 服务
        $server = ConsultingServer::where('id', $trade->serverId)->find();

        if (!$consulting || !$server) {
            // TODO 添加错误日志

            return;
        }

        $now = time();

        // 预估律师佣金（使用配置计算，结算的时候直接使用这个字段给律师结算）
        $lawyerMoney = $this->estimateLawyerMoney($trade->payMoney, $trade->settleStatus, $server);

        $trade->lawyerMoney = $lawyerMoney;
        $trade->save();

        // 激活
        $consulting->status = '1';

        // 付费后，免费咨询变成付费咨询
        if ($consulting->consultingType == 0) {
            $consulting->consultingType = 1;
            $consulting->consultingServerId = $server->id;
        }

        // 保存预估律师佣金
        $consulting->lawyerMoney = bcadd($consulting->lawyerMoney, $lawyerMoney, 2);

        // 保存
        $consulting->save();

        // 咨询变动事件
        event('ConsultingUpdated', $consulting);

        // 激活服务
        if ($consulting->businessType == Consulting::BT_RANDOM || $consulting->businessType == Consulting::BT_DESIGNATED) {

            event('ConsultingServerStart', ['consulting' => $consulting, 'server' => $server, 'trade' => $trade]);

            if ($consulting->matchType == Consulting::MATCH_TYPE_SVIP && !is_id($consulting->lawyerId)) {
                // SVIP
                $this->getConsultingLawyerMatchV3Service()->matchSvip($consulting);
            } elseif ($consulting->matchType == Consulting::MATCH_TYPE_RANDOM && !is_id($consulting->lawyerId)) {
                // 随机匹配（应该没有这种情况了，只是刚上线的时候，会有部分旧数据，先保留，以免他们BUG）
                $this->getConsultingLawyerMatchV2Service()->matchRandom0($consulting);
            } elseif ($consulting->matchType == Consulting::MATCH_TYPE_DESIGNATE) {
                // 指定律师
                $this->getConsultingLawyerMatchV2Service()->matchDesignate0($consulting);
            }

        } else {
            event('ConsultingServerStart', ['consulting' => $consulting, 'server' => $server, 'trade' => $trade]);

            // 如果随机匹配咨询还没有分配律师，那么立即分配一个
            if (!is_id($consulting->lawyerId) && $consulting->matchType == Consulting::MATCH_TYPE_RANDOM) {
                // 不可达-废弃（已经没有 基础咨询 + 随机匹配 组合的情况）

                // 已提问的 或者 电话咨询
                if ($consulting->isAsked == 1 || $server->serverType == ConsultingServer::PHONE) {

                    // 百分比卡片
                    $content = [
                        'text' => '正在为您优先匹配金牌律师，请稍等....'
                    ];
                    $this->getMessageSendService()->sendRobotMessage($consulting, null, 0, ConsultingMessage::TEXT, $content);

                    // 立即随机分配一个律师
                    $this->getConsultingLawyerMatchService()->matchRand($consulting);
                }
            }
        }

        // 通知律师
        if (is_id($consulting->lawyerId)) {

            // 短信通知律师
            // $phone = Member::where('id', $consulting->lawyerId)->value('phone');
            // if (CheckUtil::isPhoneNumber($phone)) {
            //     $this->getTemplateSmsService()->memberPay($phone, $server->name, $trade->payMoney);
            // }

            // 公众号模板消息通知律师
            $nickname = Member::where('id', $trade->memberId)->value('nickname');
            $pagepath = 'pages/lawyer/lawyer?confirm_id=' . $consulting->id;
            $this->getSubscriptionMessageService()->messagePaidConsulting($consulting->lawyerId, $server->name, $trade->payMoney, $nickname, $now, $pagepath);
        }

        $this->getPromotionCallbackService()->push($trade);

        // 保存实时播报
        $this->addBroadcast($consulting->provinceId);
    }

    // 完成退款，收回服务
    public function completionRefundTrade(Trade $trade)
    {

        // 咨询
        $consulting = Consulting::where('id', $trade->consultingId)->find();

        // 服务
        $server = ConsultingServer::where('id', $trade->serverId)->find();

        if (!$consulting || !$server) {
            // TODO 添加错误日志

            return;
        }

        // 咨询扣除预估订单律师佣金
        $consulting->lawyerMoney -= $trade->lawyerMoney;
        if ($consulting->lawyerMoney < 0) {
            $consulting->lawyerMoney = 0;
        }
        $consulting->save();

        // 咨询变动事件
        event('ConsultingUpdated', $consulting);

        // 服务回收事件
        event('ConsultingServerRefund', ['consulting' => $consulting, 'server' => $server, 'trade' => $trade]);

    }

    public function canceledTrade(Trade $trade)
    {
        return;
    }

    private function getMessageSendService(): MessageSendService
    {
        return app(MessageSendService::class);
    }

    private function getSubscriptionMessageService(): SubscriptionMessageService
    {
        return app(SubscriptionMessageService::class);
    }

    private function getConsultingLawyerMatchService(): ConsultingLawyerMatchService
    {
        return app(ConsultingLawyerMatchService::class);
    }

    private function getConsultingLawyerMatchV2Service(): ConsultingLawyerMatchV2Service
    {
        return app(ConsultingLawyerMatchV2Service::class);
    }

    private function getPromotionCallbackService(): \app\common\service\PromotionCallbackService
    {
        return app(\app\common\service\PromotionCallbackService::class);
    }

    private function getConsultingLawyerMatchV3Service(): ConsultingLawyerMatchV3Service
    {
        return app(ConsultingLawyerMatchV3Service::class);
    }
}
